package org.platform.processor.monitor.job;

import lombok.extern.slf4j.Slf4j;
import org.platform.mo.bussmo.diagnose.event.AbnormalEventBO;
import org.platform.mo.bussmo.diagnose.event.AlarmBO;
import org.platform.processor.knowledge.EventProcessor;
import org.platform.processor.monitor.data.CacheLibraryPO;
import org.platform.tool.util.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * 本线程用于检测异常队列库里面的所有设备信息是否达到报警的标准
 *
 * @author FengJie
 * @date 2018/5/22
 */
@Service
@Slf4j
public class AlarmExamineJob {
    @Autowired
    private EventProcessor service;
    private static final int ALARM_THREAD_COUNT = 0;
    private static final int ALARM_SLEEP_TIME = 3000;

    @PostConstruct
    private void init() {
        for (int i = 0; i < ALARM_THREAD_COUNT; i++) {
            AlarmThread thread = new AlarmThread();
            thread.setName("Alarm" + i);
            thread.start();
        }
    }

    class AlarmThread extends Thread {
        /**
         * 本对列存放有异常的设备
         */
        private Map<String, AbnormalEventBO> abnormalDeviceMap = CacheLibraryPO.getCacheLibraryPO().getAbnormalDeviceMap();

        /**
         * 本队列存放最终所有报警的设备信息 (级别  异常<报警 )
         */
        private Map<String, AlarmBO> alarmDeviceMap = CacheLibraryPO.getCacheLibraryPO().getAlarmDeviceMap();


        /**
         * 检查所有的异常设备,判断其值是否达到报警的值,如果达到报警的标准:
         * 1.推动到客服端
         * 2.持久化到数据库
         * 3.从异常库中删除信息
         * 4.在报警库中新增报警信息
         * </br>
         * 如果没有达到报警标准,则判断是否从异常库中删除该异常信息
         * 当前的时间-上一次上报的时间>最大的持续时间 则删除  ; 也可以用当前时间错误累积次数判断
         */
        @Override
        @SuppressWarnings("InfiniteLoopStatement")
        public void run() {
            while (true) {
                try {
                    abnormalDeviceMap.forEach((k, v) -> {
                        if (v.getCount() > v.getStandardEventBO().getReportcount()
                                || v.getCountByTime() > v.getStandardEventBO().getReporttime()) {
                            if (!alarmDeviceMap.containsKey(k)) {
                                AlarmBO alarmBO = new AlarmBO();
                                alarmBO.setId(v.getStandardEventBO().getId());
                                alarmBO.setKnowledgeid(v.getStandardEventBO().getKnowledgeid());
                                alarmBO.setHappendtime(TimeUtils.strTimeToTimestampsByFormat(v.getTimeSpan(), null));
                                alarmBO.setDeviceid(v.getDeviceId());
                                alarmBO.setDevattr(v.getStandardEventBO().getAttrid());
                                alarmBO.setDevattrval(v.getStandardEventBO().getAttrid());
                                alarmBO.setIsconfirmed(0);
                                alarmBO.setIsrestored(0);
                                //0L 表示未恢复正常
                                alarmBO.setRestoretime(0L);
                                alarmDeviceMap.put(k, alarmBO);
                                service.addOrModifyEventByStation(alarmBO);
                            }
                        } else {
                            long firstStorageTime = TimeUtils.strTimeToTimestampsByFormat(v.getTimeSpan(), null);
                            long currentTime = System.currentTimeMillis();
                            if ((currentTime - firstStorageTime) / 1000 > v.getStandardEventBO().getReporttime()) {
                                abnormalDeviceMap.remove(k);
                            }
                        }
                    });
                    Thread.sleep(ALARM_SLEEP_TIME);
                } catch (Exception e) {
                    log.error("报警设备入库异常:  ", e);
                }
            }
        }
    }
}